package com.bestcem.xm.qdes.handler.impor.type;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.bestcem.xm.qdes.handler.impor.KeyWordHandler;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

import static com.bestcem.xm.qdes.enums.QuestionDescTypeEnum.QUESTION_TYPE_AUTOTABLE;
import static com.bestcem.xm.qdes.enums.QuestionTypeEnum.*;

@Component
public class KeywordOptionsHandler implements KeyWordHandler {
    private static final Pattern ATTR_PATTERN = Pattern.compile("\\[(.*?)\\]");
    private static final Pattern COL_PATTERN = Pattern.compile("每行(\\d+)列");
    private static final Pattern TYPE_PATTERN = Pattern.compile("^(下拉单选|不限|整数|小数|字母|中文|邮件|日期|手机号码|固话|手机/固话|身份证号)$");
    private static final Pattern MIN_PATTERN = Pattern.compile("最小值(\\d+)");
    private static final Pattern MAX_PATTERN = Pattern.compile("最大值(\\d+)");
    private static final Pattern LESS_PATTERN = Pattern.compile("最少#(\\d+)");
    private static final Pattern MORE_PATTERN = Pattern.compile("最多#(\\d+)");
    private static final Pattern NUM_PATTERN = Pattern.compile("小数位数#(\\d+)");
    private static final Pattern YEAR_PATTERN = Pattern.compile("^(年月日|年月|年)$");

    @Override
    public Integer handler(String qType, JSONArray rawItems, JSONObject questionDict) {
        // 选项解析
        if (rawItems == null || rawItems.isEmpty()) {
            return 0;
        }
        JSONArray rowOptionCommon = Optional.ofNullable(rawItems.getJSONArray(0)).orElse(new JSONArray());
        String optionAttrStr = rowOptionCommon.size() > 2 ? rowOptionCommon.getString(2).trim() : "";
        questionDict.putAll(parseOptionCoomonAttr(optionAttrStr));
        boolean isAutotable = QUESTION_TYPE_AUTOTABLE.getDispType().endsWith(qType);
        JSONArray rawOptions = new JSONArray();
        if (rowOptionCommon.size() > 1) {
            for (int i = 1; i < rawItems.size(); i++) {
                rawOptions.add(rawItems.get(i));
            }
        }
        JSONArray retItems = new JSONArray();
        questionDict.put("items", retItems);
        String dispSelect = Optional.ofNullable(questionDict.getString("dispSelect")).orElse("");
        boolean codeSelect = Optional.ofNullable(questionDict.getBoolean("codeSelect")).orElse(false);

        boolean hasJumpCode = false;
        int totalGidCountTmp = rawOptions.size();
        for (int i = 0; i < rawOptions.size(); i++) {
            JSONArray rawOption = rawOptions.getJSONArray(i);
            Object optionCid = rawOption.get(0);
            Object optionTitle = rawOption.get(1);
            String optionAttr = rawOption.size() > 2 ? rawOption.getString(2) : "";
            String dispPlasterCode = rawOption.size() > 3 ? rawOption.getString(3) : ""; // 显示代码/抹灰代码
            String jumpCode = rawOption.size() > 4 ? rawOption.getString(4) : ""; // 跳转代码
            String autoCode = rawOption.size() > 5 ? rawOption.getString(5) : ""; // 自动勾选代码

            JSONObject optionDict = new JSONObject();
            optionDict.put("oid", optionCid);
            optionDict.put("title", optionTitle);
            optionDict.put("type", "O");
            if (isAutotable) {
                optionDict.putAll(parseAutotableOptionAttr(optionAttr));
            } else {
                optionDict.putAll(parseOptionAttr(optionAttr, qType));
            }
            if ("1".equals(dispSelect) && codeSelect) {
                // 显示代码
                optionDict.put("disp_code", dispPlasterCode);
            } else if ("1".equals(dispSelect) && !codeSelect) {
                // 抹灰代码
                optionDict.put("plaster_code", dispPlasterCode);
            }

            if (StringUtils.isNotEmpty(jumpCode)) {
                hasJumpCode = true;
                optionDict.put("jump_code", jumpCode);
            }
            if (StringUtils.isNotEmpty(autoCode)) {
                optionDict.put("auto_code", autoCode);
            }
            retItems.add(optionDict);
        }
        if (hasJumpCode) {
            questionDict.put("jumpSelect", 1);
        }
        return totalGidCountTmp;
    }

    @Override
    public String getType() {
        return "选项";
    }

    private JSONObject parseOptionCoomonAttr(String attrstr) {
        // 解析选项标签的属性设置
        JSONObject retDict = new JSONObject();
        if (StringUtils.isEmpty(attrstr)) {
            return retDict;
        }

        // [顺序#随机][关联#Q1#未选中项][关联#Q11#未选中项] -->  ['顺序#随机', '关联#Q1#未选中项', '关联#Q11#未选中项']
        Matcher attrMatcher = ATTR_PATTERN.matcher(attrstr);
        List<String> attributes = new ArrayList<>();
        while (attrMatcher.find()) {
            attributes.add(attrMatcher.group(1));
        }

        for (String attr : attributes) {
            attr = attr.trim();
            if (attr.startsWith("顺序#")) {
                String val = attr.split("#")[1];
                retDict.put("options_random", "随机".equals(val) ? true : "循环".equals(val) ? "sort" : "倒序"
                    .equals(val) ? "reverse" : false);
            } else if (attr.startsWith("排列#")) {
                String[] vals = attr.split("#");
                if (vals.length > 1) {
                    String optionAlign = vals[1];
                    if ("竖排".equals(optionAlign)) {
                        retDict.put("align", "vertical");
                    } else if ("横排".equals(optionAlign)) {
                        retDict.put("align", "horizontal");
                        retDict.put("column_value", 2); // 默认每行2列
                        String columnValuestr = vals.length > 2 ? vals[2] : "";
                        Matcher matcher = COL_PATTERN.matcher(columnValuestr);
                        if (matcher.find()) {
                            retDict.put("column_value", Integer.parseInt(matcher.group(1)));
                        }
                    }
                }
            } else if (attr.startsWith("关联#")) {
                String[] vals = attr.split("#");
                if (vals.length > 1) {
                    String relatedGcid = vals[1]; // 关联的题目cid
                    String modeDesc = vals.length > 2 ? vals[2] : "";
                    String mode = "未选中项".equals(modeDesc) ? "unselect" : "select";
                    // {
                    //                    "sourceGid": 65,
                    //                    "targetGid": 83,
                    //                    "type": "O",
                    //                    "mode": "unselect"
                    //                }
                    JSONArray relatedRefs = Optional.ofNullable(retDict.getJSONArray("relatedRefs")).orElse(new JSONArray());
                    JSONObject oneRef = new JSONObject();
                    oneRef.put("sourceQcid", relatedGcid);
                    oneRef.put("type", "O");
                    oneRef.put("mode", mode);
                    relatedRefs.add(oneRef);
                    retDict.put("relatedRefs", relatedRefs);
                }
            }
        }
        return retDict;
    }

    private JSONObject parseAutotableOptionAttr(String attrstr) {
        // 解析自增表格题的 选项的属性设置
        JSONObject retDict = new JSONObject();
        JSONObject openAttrs = new JSONObject();
        openAttrs.put("required", true);
        openAttrs.put("type", 0);
        openAttrs.put("range", new JSONArray());

        retDict.put("is_open", false);
        retDict.put("required", true);
        retDict.put("unique", "none");
        retDict.put("open_attrs", openAttrs);
        retDict.put("setType", "unlimit");
        retDict.put("setValue", Arrays.asList("", ""));

        if (StringUtils.isEmpty(attrstr)) {
            return retDict;
        }

        // [禁止选项关联][输入框高度#中][开放#必填#唯一#手机号码] --> ['禁止选项关联', '输入框高度#中', '开放#必填#唯一#手机号码']
        Matcher attrMatcher = ATTR_PATTERN.matcher(attrstr);
        List<String> attributes = new ArrayList<>();
        while (attrMatcher.find()) {
            attributes.add(attrMatcher.group(1));
        }
        String otype = "不限";
        if (CollectionUtils.isNotEmpty(attributes)) {
            String attr = attributes.get(0);
            if (TYPE_PATTERN.matcher(attr).find()) {
                otype = attr.trim();
            }
        }

        switch (otype) {
            case "下拉单选":
                retDict.put("setType", "select");
                break;
            case "不限":
                retDict.put("setType", "unlimit");
                break;
            case "整数":
                retDict.put("setType", "int");
                break;
            case "小数":
                retDict.put("setType", "decimal");
                break;
            case "字母":
                retDict.put("setType", "en");
                break;
            case "中文":
                retDict.put("setType", "zh");
                break;
            case "邮件":
                retDict.put("setType", "email");
                break;
            case "日期":
                retDict.put("setType", "date");
                break;
            case "手机号码":
                retDict.put("setType", "mobile");
                break;
            case "固话":
                retDict.put("setType", "tel");
                break;
            case "手机/固话":
                retDict.put("setType", "mobile_tel");
                break;
            case "身份证号":
                retDict.put("setType", "idCard");
                break;
            default:
        }

        if (attributes.size() > 1) {
            for (int i = 1; i < attributes.size(); i++) {
                String oattr = attributes.get(i);
                if ("必答".equals(oattr)) {
                    retDict.put("required", true);
                } else if ("唯一".equals(oattr)) {
                    retDict.put("unique", true);
                } else if (oattr.startsWith("最小值#")) {
                    Matcher matcher = MIN_PATTERN.matcher(oattr);
                    if (matcher.find()) {
                        String minNumb = matcher.group(1);
                        JSONArray optionsRange = retDict.getJSONArray("setValue");
                        if (optionsRange == null || StringUtils.isEmpty(optionsRange.getString(0))) {
                            optionsRange = new JSONArray();
                            optionsRange.add(0);
                            optionsRange.add(0);
                        }
                        optionsRange.set(0, Integer.parseInt(minNumb));
                        retDict.put("setValue", optionsRange);
                    }
                } else if (oattr.startsWith("最大值#")) {
                    Matcher matcher = MAX_PATTERN.matcher(oattr);
                    if (matcher.find()) {
                        String maxNumb = matcher.group(1);
                        JSONArray optionsRange = retDict.getJSONArray("setValue");
                        if (optionsRange == null || StringUtils.isEmpty(optionsRange.getString(0))) {
                            optionsRange = new JSONArray();
                            optionsRange.add(0);
                            optionsRange.add(0);
                        }
                        optionsRange.set(1, Integer.parseInt(maxNumb));
                        retDict.put("setValue", optionsRange);
                    }
                } else if (oattr.startsWith("最少#")) {
                    Matcher matcher = LESS_PATTERN.matcher(oattr);
                    if (matcher.find()) {
                        int minNumb = Integer.parseInt(matcher.group(1));
                        JSONArray optionsRange = retDict.getJSONArray("setValue");
                        if (optionsRange == null || StringUtils.isEmpty(optionsRange.getString(0))) {
                            optionsRange = new JSONArray();
                            optionsRange.add(0);
                            optionsRange.add(0);
                        }
                        optionsRange.set(0, minNumb);
                        retDict.put("setValue", optionsRange);
                    }
                } else if (oattr.startsWith("最多#")) {
                    Matcher matcher = MORE_PATTERN.matcher(oattr);
                    if (matcher.find()) {
                        int maxNumb = Integer.parseInt(matcher.group(1));
                        JSONArray optionsRange = retDict.getJSONArray("setValue");
                        if (optionsRange == null || StringUtils.isEmpty(optionsRange.getString(0))) {
                            optionsRange = new JSONArray();
                            optionsRange.add(0);
                            optionsRange.add(0);
                        }
                        optionsRange.set(1, maxNumb);
                        retDict.put("setValue", optionsRange);
                    }
                } else if (oattr.startsWith("小数位数#")) {

                    Matcher matcher = NUM_PATTERN.matcher(oattr);
                    int pozSize = 2;
                    if (matcher.find()) {
                        pozSize = Integer.parseInt(matcher.group(1));
                    }
                    JSONArray optionsRange = retDict.getJSONArray("setValue");
                    if (optionsRange == null || StringUtils.isEmpty(optionsRange.getString(0))) {
                        optionsRange = new JSONArray();
                        optionsRange.add(0);
                        optionsRange.add(0);
                        optionsRange.add(0);
                    } else if (optionsRange.size() < 3) {
                        optionsRange.add(0);
                    }
                    optionsRange.set(2, pozSize);
                    retDict.put("setValue", optionsRange);
                } else if (oattr.startsWith("选项#")) {
                    List<String> values = Arrays.stream(oattr.substring(3).split(","))
                        .filter(StringUtils::isNotEmpty).map(String::trim).collect(Collectors.toList());
                    if (CollectionUtils.isNotEmpty(values)) {
                        retDict.put("setValue", String.join(";", values));
                    }
                } else if (YEAR_PATTERN.matcher(oattr).find()) {
                    String rangeTxt = "";
                    switch (oattr) {
                        case "年":
                            rangeTxt = "yyyy";
                            break;
                        case "年月":
                            rangeTxt = "yyyy-MM";
                            break;
                        case "年月日":
                            rangeTxt = "yyyy-MM-dd";
                            break;
                        default:
                            rangeTxt = "";
                    }
                    retDict.put("setValue", rangeTxt);
                }
            }
        }
        return retDict;
    }

    private JSONObject parseOptionAttr(String attrstr, String qtype) {
        // 解析选项的属性设置
        JSONObject retDict = new JSONObject();

        //  #10437 填空题 选项开放框默认设置
        boolean isBlankOption = Arrays.asList(QUESTION_TYPE_BLANK.getValue(), QUESTION_TYPE_MULTIPLE_BLANK.getValue(),
            QUESTION_TYPE_MATRIX_BLANK.getValue()).contains(qtype);
        if (isBlankOption) {
            retDict.putAll(parseOptionOpen(null));
        }

        if (StringUtils.isEmpty(attrstr)) {
            return retDict;
        }

        boolean isMatrixBlank = QUESTION_TYPE_MATRIX_BLANK.getValue().equals(qtype);
        boolean isMultipleBlank = QUESTION_TYPE_MULTIPLE_BLANK.getValue().equals(qtype);

        // [禁止选项关联][输入框高度#中][开放#必填#唯一#手机号码] --> ['禁止选项关联', '输入框高度#中', '开放#必填#唯一#手机号码']
        Matcher attrMatcher = ATTR_PATTERN.matcher(attrstr);
        List<String> attributes = new ArrayList<>();
        while (attrMatcher.find()) {
            attributes.add(attrMatcher.group(1));
        }

        for (String attr : attributes) {
            attr = attr.trim();
            if ("禁止选项关联".equals(attr)) {
                retDict.put("forbidRelated", true);
            } else if (attr.startsWith("输入框高度#")) {
                String val = attr.split("#")[1];
                retDict.put("inputbox_height", "小".equals(val) ? "small" : "中".equals(val) ? "middle" : "大"
                    .equals(val) ? "big" : "");
            } else if ("选项排他".equals(attr)) {
                retDict.put("exclusive", true);
            } else if ("固定".equals(attr)) {
                retDict.put("fixed", true);
            } else if (attr.startsWith("开放") || isMatrixBlank) {
                List<String> vals = Arrays.stream(attr.split("#")).collect(Collectors.toList());
                if ("开放".equals(vals.get(0))) {
                    retDict.put("is_open", false);
                    if (!isMultipleBlank) {
                        retDict.put("is_open", true);
                    }
                    retDict.putAll(parseOptionOpen(vals.subList(1, vals.size())));
                } else {
                    retDict.putAll(parseOptionOpen(vals));
                }
            }
        }
        return retDict;
    }
}
